#include "3_3pv.h"
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};


//初始化semnums个信号灯，信号量的值（value）

int I(int semnums,int value){

    int semid;
    semid=semget(IPC_PRIVATE,semnums,IPC_CREAT|IPC_EXCL|0777);//创建信号两级
    if(semid<0){
        return -1;
    }

    //
    union semun un;
    unsigned short *array=(unsigned short*)calloc(semnums,sizeof(unsigned short));
    int i;
    for(int i=0;i<semnums;i++){
        array[i]=value;
    }

    un.array=array;
    //初始化信号量集所有信号灯的初值
    if(semctl(semid,0,SETALL,un)<0){
        perror("semctl");
        return -1;
    }

    free(array);
    return semid;

}

//p操作
void P(int semid,int semnum,int value){
    assert(value>=0);
    //定义sembuf数组，放置若干个结构体变量
    struct sembuf ops[]={{semnum,-value,SEM_UNDO}};


    if(semop(semid,ops,sizeof(ops))<0){

        perror("semop");

    }


}


//v操作
void V(int semid,int semnum,int value){
     assert(value>=0);
    //定义sembuf数组，放置若干个结构体变量
    struct sembuf ops[]={{semnum,value,SEM_UNDO}};


    if(semop(semid,ops,sizeof(ops))<0){

        perror("semop");
        
    }

}



//销毁信号量集
void D(int semid){

    if(semctl(semid,0,IPC_RMID,NULL)<0){
        perror("semctl error");
    }

}